New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WICKET-6465 prevent unbound during storeTouchedPages only #233
Conversation
We should consider method Session.destroy() to remove pages when session expires. See my comment at https://issues.apache.org/jira/browse/WICKET-6465 |
When the session expires or is invalidated via API call then |
Indeed, Sesison.destroy() is only called under certain conditions, and in those conditions, valueUnbound() will also be called. |
I see. thank you for the clarification. Still, I'd like to evaluate more structural solutions, at least for Wicket 8. A good start point might be HttpSessionStore.SessionBindingListener#valueUnbound. |
Currently HttpSessionStore and PageStoreManager each use their own instance of HttpSessionBindingListener. It was unfortunate that we didn't consider all possible callbacks from Servlet containers when this problem started with WICKET-6356.
Andrea, what do you think? BTW do we have to take care of concurrent access to the SessionEntry? I see that Martin used an AtomicBoolean, but how does that help if there are two request simultaneously storing touched pages? |
I'm fine with this quick fix, but I warmly suggest to improve it after it has been applied, at least in master branch. About concurrent access afaik we do have to take care of concurrency. At the moment we don't have any guarantee that setSessionAttribute saves the entry for the last request submitted (for the same session). |
I don't see why the current implementation uses |
I agree about the use of a normal boolean, but I'm not sure I've understood your idea about ThreadLocal. What I would like to do is to prevent race conditions inside storeTouchedPages. I would do it using synchronized on entry object:
In this way two possible concurrent requests for the same session would execute storeTouchedPages one at a time. |
We don't care about concurrent calls to valueUnbound, that's fine. All code in that method is thread safe. What we don't want is multiple calls to storeTouchedPages and valueUnbound (session expiry) to interfere with each other. Synchronizing on the entry will not help as session expiry is probably done from a different thread. |
I agree
Yes, synchronizing is meant to prevent problems for multiple invocations of storeTouchedPages for the same session, valueUnbound is unaffected. The boolean value should be enough to tell if valueUnbound is invoked as result of session expiration. |
No, a boolean won't work. Suppose the following happens: A thread calls storeTouchedPages, setting the boolean to true. At the same time, another thread unbinds the session, calling valueUnbound. This will leak the page store. We only want valueUnbound to be ignored when its a side effect of calling storeTouchedPages. This is local to the thread calling the method, hence ThreadLocal. |
Got it. That's way I hope for a future improvement of this boolean-based solution :-). |
Agreed, a ThreadLocal makes sense. |
Yes, this is what I had in mind. I'm ok to merge this in 7.x and 8. |
Don't forget to fix brackets indentation before commit |
Why so complicated? We just want to prevent valueUnbound() from doing any harm while we're resetting the attribute during storeTouchedPages.